package com.lm.activiti;

import com.lm.activiti.dto.Person;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipInputStream;

/**
 * @author lm_jcf
 * @date 2018/5/7 17:52
 */
public class ProcessVariablesTest {


    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //    部署流程定义
    @Test
    public void deploymentProcessDefinition() throws FileNotFoundException {
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("leaveBill2.rar");
        ZipInputStream zipInputStream = new ZipInputStream(in);

        Deployment deployment = processEngine.getRepositoryService()    //与流程定义和部署对象相关的额Service
                .createDeployment()     //创建一个部署对象
                .name("流程变量 ")
//                .addClasspathResource("bpmn/processVariables.bpmn")    //加载资源dpmn
                .addZipInputStream(zipInputStream)
                .deploy();   //完成部署


        System.out.println("流程Id"+deployment.getId());  //  601
        System.out.println("流程名称"+deployment.getName());

    }


    // 启动流程定义
    @Test
    public void startProcessInstance(){
        String processKey = "processVariables";
        ProcessInstance pi = processEngine.getRuntimeService()      //与正在执行的流程实例和执行对象相关的Service
                .startProcessInstanceByKey(processKey);     //使用流程定义的Key启动流程实例，可以使之每次都启动最新版本的流程。
        System.out.println("流程实例ID："+pi.getId());
        System.out.println("流程定义ID："+pi.getProcessDefinitionId());
    }

    @Test
    public void findMyProcessTask() {
        String assignee = "小小";
        List<Task> lists = processEngine.getTaskService()  //与正在执行的任务相关的Service
                .createTaskQuery()  //创建任务查询对象
                /** 查询条件  */
                .taskAssignee(assignee) //指定个人任务对象
//                .taskCandidateUser(taskCandidateUser) //组任务的办理人
//                .processDefinitionId()  //使用流程定义Id查询
//                .processInstanceId()    //使用流程实例ID
//                .executionId()  //使用执行对象id查询
                /** 排序*/
                .orderByTaskCreateTime().asc()  //使用创建时间升序排序
                /** 返回结果集*/
//                .singleResult()   //唯一结果集
//                .count()  //返回结果集的数量
//                .listPage()   //分页查询
                .list();

        if (lists != null && lists.size() > 0) {
            for (Task task : lists) {
                System.out.println("任务ID:" + task.getId());
                System.out.println("任务名称:" + task.getName());
                System.out.println("任务创建时间:" + task.getCreateTime());
                System.out.println("任务办理人:" + task.getAssignee());
                System.out.println("流程实例ID:" + task.getProcessInstanceId());
                System.out.println("执行对象ID:" + task.getExecutionId());
                System.out.println("流程定义ID:" + task.getProcessDefinitionId());
            }
        }

    }
    //设置流程变量
    @Test
    public void setVariables(){

        TaskService taskService = processEngine.getTaskService();
        //任务ID
        String taskID = "1304";
        //设置流程变量,使用基本数据类型
//        taskService.setVariableLocal(taskID,"请假原因","回家binary"); //与任务ID绑定,当前任务才有效，完成任务后失效
//        taskService.setVariable(taskID,"请假天数",3);
//        taskService.setVariable(taskID,"请假日期",new Date());
        //设置流程变量，使用javabean类型
        Person p = new Person();
        p.setId(10);
        p.setName("花花");
        taskService.setVariable(taskID,"人员信息",p);

        System.out.println("设置任务变量成功");
    }

    //获取流程变量
    @Test
    public void getVariables(){
        TaskService taskService = processEngine.getTaskService();
        String taskId = "1304";
        //使用基本数据类型
//        Integer days = (Integer) taskService.getVariable(taskId,"请假天数");
//        Date time = (Date) taskService.getVariable(taskId,"请假日期");
//        System.out.println("请假天数:"+days);
//        System.out.println("请假日期:"+time);
        //使用javabean类型
        //当一个javabean放置到流程变量中，要求javabean的属性不能再发生变化，如果发生变化，再获取的时候，抛出异常。
        // 解决方案：使javabean序列化，并生成版本号。
        Person p = (Person) taskService.getVariable(taskId,"人员信息");
        System.out.println(p.getId()+p.getName()+p.getAge());


    }


    @Test
    public void completeMyProcessTask(){
        String taskId = "1002";
        processEngine.getTaskService()
                .complete(taskId);
        System.out.println("完成任务");
    }

    //模拟设置流程变量
    @Test
    public void setAndGetVariables(){
        //与流程实例，执行对象（正在执行）


        RuntimeService runtimeService = processEngine.getRuntimeService();
        //任务
        TaskService taskService = processEngine.getTaskService();

//        runtimeService.setVariable();       //使用执行对象ID，和流程变量的名称，设置流程变量（一次一个值）
//        runtimeService.setVariables();        //使用执行对象ID，和Map集合设置流程变量，map的KEy就是流程变量的名称，（一次多个）

//        taskService.setVariable();       //使用任务对象ID，和流程变量的名称，设置流程变量（一次一个值）
//        taskService.setVariables();        //使用任务对象ID，和Map集合设置流程变量，map的KEy就是流程变量的名称，（一次多个）

//        runtimeService.startProcessInstanceByKey()        //启动流程实例的同时,设置变量
//        taskService.complete();   //完成任务的同时,设置变量

//        runtimeService.getVariable(executionId,variableName) //使用执行对象ID和流程变量获取变量的值
//        runtimeService.getVariables(executionId)   //使用执行对象ID获取所有的流程变量，返回Map集合
//        runtimeService.getVariables(executionId,variableNames) //使用执行对象Id，获取流程变量，获取指定流程变量名称的值

//        taskService.getVariable(taskId,variableName) //使用任务ID和流程变量获取变量的值
//        taskService.getVariables(taskId)   //使用任务ID获取所有的流程变量，返回Map集合
//        taskService.getVariables(taskId,variableNames) //使用任务对象Id，获取流程变量，获取指定流程变量名称的值
    }

}
